package edu.gdpu.memory.heap;

import java.util.ArrayList;

/**
 * @author mazebin
 * @date 2021年 07月09日 23:14:44
 * 关于Java对象创建的过程:
 * new关键字创建对象的3个步骤:
 * 1.在堆内存中创建出对象的实例。
 * 2.为对象的实例成员变量赋初值。
 * 3.将对象的引用返回
 * 指针碰撞(前提是堆中的空间通过一个指针进行分割，一侧是已经被占用的空间，另一侧是未被占用的空间)
 * 空闲列表(前提是堆内存空间中已被使用与未被使用的空间是交织在一起的，这时，虚拟机就需要通过一个列表来记录哪些空间是可以使用的，
 * 哪些空间是已被使用的，接下来找出可以容纳下新创建对象的且未被使用的空间，在此空间存放该对象，同时还要修改列表上的记录)
 * 对象在内存中的布局:
 * 1.对象头.
 * 2.实例数据(即我们在一个类中所声明的各项信息)
 * 3.对齐填充(可选) !
 * 引用访问对象的方式:
 * 1.使用句柄的方式。
 * 2.使用直接指针的方式。
 */
public class HeapOutOfMemoryErrorTest1 {
    public static void main(String[] args) {
        //-Xms5m -Xmx5m -XX:+HeapDumpOnOutOfMemoryError
        // 设置jvm对空间最小和最大以及遇到错误时把堆存储文件打印出来  -XX:HeapDumpPath=D:\dump
        //Java堆用于存储对象实例，只要不断地创建对象，当对象数量到达最大堆的容量限制后就会产生内存溢出异常。最常见的内存溢出就是存在大的容器，而没法回收，比如：Map，List等。
        // 出现下面信息就可以断定出现了堆内存溢出。
        // java.lang.OutOfMemoryError: Java heap space
        //内存溢出：内存空间不足导致，新对象无法分配到足够的内存；
        //内存泄漏：应该释放的对象没有被释放，多见于自己使用容器保存元素的情况下。
        //作者：xiaolyuh
        //链接：https://www.jianshu.com/p/2ba4019b819d
        //来源：简书
        //著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
        //使用Jvisualvm打开磁盘上的转存文件，分析发现
        //dump文件中的实例列表其实是反映了使用的堆的情况，
        // 而使用的堆内存并没有达到预先设置的最大堆内存，只是在申请堆内存的过程中超出了预先设置的最大堆内存，然后内存溢出。
        //https://blog.csdn.net/lkforce/article/details/60878295?utm_source=blogkpcl7

        ArrayList<HeapOutOfMemoryErrorTest1> objects = new ArrayList<>();
        int i=0;
        while (true){
           objects.add(new HeapOutOfMemoryErrorTest1());
           // System.gc();

        }
    }
}
